import 'dart:async';
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:meta/meta.dart';

import 'auth_strings.dart';
import 'error_codes.dart';

enum BiometricType { face, fingerprint, iris }

class FistLocalAuth {
  static const MethodChannel _channel =
      const MethodChannel('auth.plugins.flutter.io/fist_local_auth');

  Future<bool> authenticateWithBiometrics({
    @required String localizedReason,
    bool useErrorDialogs = true,
    bool stickyAuth = false,
    AndroidAuthMessages androidAuthStrings = const AndroidAuthMessages(),
    IOSAuthMessages iOSAuthStrings = const IOSAuthMessages(),
  }) async {
    assert(localizedReason != null);
    final Map<String, Object> args = <String, Object>{
      'localizedReason': localizedReason,
      'useErrorDialogs': useErrorDialogs,
      'stickyAuth': stickyAuth,
    };
    if (Platform.isIOS) {
      args.addAll(iOSAuthStrings.args);
    } else if (Platform.isAndroid) {
      args.addAll(androidAuthStrings.args);
    } else {
      throw PlatformException(
          code: otherOperatingSystem,
          message: 'Local authentication does not support non-Android/iOS '
              'operating systems.',
          details: 'Your operating system is ${Platform.operatingSystem}');
    }
    return await _channel.invokeMethod<bool>(
        'authenticateWithBiometrics', args);
  }

  Future<bool> deleteKey() async {
    return await _channel.invokeMethod<bool>('clearKeys');
  }

  Future<bool> touchIdInfoDidChange() async {
    return await _channel.invokeMethod<bool>('touchIdInfoDidChange');
  }


  Future<bool> get canCheckBiometrics async =>
      (await _channel.invokeListMethod<String>('getAvailableBiometrics'))
          .isNotEmpty;

  Future<List<BiometricType>> getAvailableBiometrics() async {
    final List<String> result =
        (await _channel.invokeListMethod<String>('getAvailableBiometrics'));
    final List<BiometricType> biometrics = <BiometricType>[];
    result.forEach((String value) {
      switch (value) {
        case 'face':
          biometrics.add(BiometricType.face);
          break;
        case 'fingerprint':
          biometrics.add(BiometricType.fingerprint);
          break;
        case 'iris':
          biometrics.add(BiometricType.iris);
          break;
        case 'undefined':
          break;
      }
    });
    return biometrics;
  }
  Future<String> getAvailableBiometricsWithIos() async {

    var type = "TouchId";

    final List<String> result =
    (await _channel.invokeListMethod<String>('getAvailableBiometrics'));
    result.forEach((String value) {
      switch (value) {
        case 'face':
          type = "FaceId";
          break;
        case 'fingerprint':
          type = "TouchId";
          break;
        case 'iris':
          break;
        case 'undefined':
          break;
      }
    });


    return type;
  }
}
